const { MapRoute } = require('./A star.js')
const utilApi = require('../../utils/util.js')
const alertApi = require('../../utils/alert.js')
const { Canvas } = require('./draw.js')
const app = getApp()
var that
/* canvas: 绘画类 ctx: 绘图上下文 primCoord: 当前位置坐标 canvasRoute: 当前路径 */
/* drawTTL: 画布刷新时间间隔; getTTL: 位置刷新时间间隔; navTTL: 导航路径刷新时间间隔 */

var canvas, ctx, canvasNode, primCoord, affiCoord = []
var mapRoute, canvasRoute
var timer = {drawTTL:50, getTTL:50, navTTL:100, affiReq: []}
var audio, warnAudio
var flag = {
  warnAlert: false,
  warnAudio: false,
  warnVibrate: false,
  primToken: true,
  affiToken: [],
  exhArr: []
}

var info={
  bgpic: {}, //背景图片相关信息
  de: {},    //设备相关信息
  URL: {//图像链接
    bg: "/images/lab.png",
    icon: "/images/road_icon.png",
    base: "/images/base.png",
    end: "/images/end.png",
    audioURL: [
      "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/out.mp3",
      "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/compass.mp3",
      "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/paper.mp3",
      "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/fire.mp3",
      "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/print.mp3",
    ],
    warnURL: "cloud://cloud1-3g1yerk2e342b1a8.636c-cloud1-3g1yerk2e342b1a8-1306547956/12762.mp3"
  },
  img: {},
  grid: { col:62, row: 131},    //绘图表格参数
  rOOLArea: [{"x1":1100, "x2":1439, "y1":0, "y2":270},], //禁区的坐标
  map: { max_x: 1439.6, max_y: 678.4}
}
const exhArea = [//(x1,y1,x2,y2) 单位厘米
  {"x1":1280, "x2":1370, "y1":420, "y2":600},  // 0
  {"x1":290, "x2":350, "y1":22, "y2":255},    // 1
  {"x1":550, "x2":610, "y1":405, "y2":630},   // 2
  {"x1":830, "x2":900, "y1":22, "y2":255},    // 3
  {"x1":1090, "x2":1160, "y1":405, "y2":630}, // 4
]
const exhDes = [
  {"x": 15, "y": 119},  // 0
  {"x": 48, "y": 28},   // 1
  {"x": 15, "y": 52},   // 2
  {"x": 48, "y": 78},   // 3
  {"x": 15, "y": 102},  // 4
]
const barriers = [  //障碍物坐标
  {"x1": 0, "x2": 27, "y1": 21, "y2": 27}, 
  {"x1": 0, "x2": 27, "y1": 32, "y2": 49},
  {"x1": 0, "x2": 27, "y1": 55, "y2": 98},
  {"x1": 0, "x2": 27, "y1": 105, "y2": 111},
  {"x1": 36, "x2": 62, "y1": 20, "y2": 26},
  {"x1": 36, "x2": 62, "y1": 31, "y2": 75},
  {"x1": 36, "x2": 62, "y1": 81, "y2": 100},
  {"x1": 36, "x2": 62, "y1": 106, "y2": 112},
  {"x1": 36, "x2": 62, "y1": 117, "y2": 123},
  {"x1": 38, "x2": 54, "y1": 11, "y2": 20},
  {"x1": 10, "x2": 29, "y1": 123, "y2": 130},
]

Page({
  data: { //页面的初始数据
    flag: {
      nav: false,
      primID: false,
      idNava:false
    },
    bottom:0,
    alert: {},
    canvasStyle:{},
    showLeft: {},
  },

  onLoad: function () { // 生命周期函数--监听页面加载
    that = this
    /* 基本信息加载 */
    info.de.width = wx.getSystemInfoSync().screenWidth
    info.de.dpr = wx.getSystemInfoSync().pixelRatio
    info.grid.size = info.de.width / info.grid.col
    for(var i in exhArea) flag.exhArr[i] = true

    /* 地图生成加载 */
    info.map2d = []
    for(var i = 0; i < info.grid.row; i++ ){
      var ROW = []
      for(var j = 0; j < info.grid.col; j++ ) ROW.push(0)
      info.map2d.push(ROW)
    }
    this.bannedMap(info.map2d)
    mapRoute = new MapRoute(info.map2d)

    /* 异步 —— 画布及背景图片加载 */
    wx.getImageInfo({
      src: info.URL.bg ,
      success (res) {
        info.bgpic.width = res.width
        info.bgpic.height = res.height
        info.bgpic.ratio = res.height / res.width
        // 坐标变换
        info.OOLArea = []
        for(var i in info.rOOLArea)
          info.OOLArea[i] = that.covCoord(info.rOOLArea[i], info, 3)
        // 画布样式加载
        that.data.canvasStyle.width = info.de.width   
        that.data.canvasStyle.height = info.de.width * info.bgpic.ratio
        that.setData({
          canvasStyle: that.data.canvasStyle
        })
        // 画笔加载
        const query = wx.createSelectorQuery()
        query.select('#myCanvas')
          .fields({ node: true, size: true })
          .exec((res) => {
            canvasNode = res[0].node
            canvasNode.width  = res[0].width * info.de.dpr
            canvasNode.height = res[0].height * info.de.dpr
            ctx = canvasNode.getContext('2d')
            ctx.scale(info.de.dpr, info.de.dpr)
            canvas = new Canvas(info, canvasNode)
          })
      }
    })

    /* 音频加载 */
    warnAudio = wx.createInnerAudioContext()
    warnAudio.src = info.URL.warnURL
    warnAudio.loop = false
    warnAudio.onPause(function () { flag.warnAudio = false })
    warnAudio.onEnded(function () { flag.warnAudio = false })
    audio = new Array(info.URL.audioURL.length)
    for(var i in info.URL.audioURL){
      audio[i] = wx.createInnerAudioContext(true)
      audio[i].src = info.URL.audioURL[i]
      audio[i].loop = false
      audio[i].onPause(()=>{ flag.onPlayID = -1 })
      audio[i].onEnded(()=>{ flag.onPlayID = -1 })
    }
  },

  onShow:async function () {
    // 初始化
    if(that.data.flag.nav && app.globalData.tourOrder.length == 0) this.endNavigation()
    flag.onPlayID = -1, flag.warnAudio = 0, flag.warnAlert = 0, flag.warnVibrate = 0

    // 核验primID
    if(app.globalData.affiID.length == 0) affiCoord = []
    if(!that.data.flag.primID){
      if(!app.globalData.primID) {alertApi.tipsInfo(that, "请先上传设备ID"); flag.idNav = true}
      else {
        flag.idNav = false
        that.data.bottom = 70
        that.data.flag.primID = true
        if(primCoord == undefined) primCoord = {x:10,y:10}
        this.setData({ flag: that.data.flag, bottom:that.data.bottom })
        alertApi.hideTips(that)
      }
    }

    // 刷新画布
    timer.drawCanvas = setInterval(() => {
      var locCoord = [...affiCoord]
      if(primCoord) locCoord.unshift(primCoord)
      if(canvas){
        canvasNode.requestAnimationFrame(()=>{
          ctx.clearRect(0, 0, 749, 1080)
          canvas.drawBackGround(ctx)
          if(that.data.flag.nav) canvas.drawRoute(ctx, canvas.toCanvasRoute(canvasRoute))
          if(locCoord.length > 0) canvas.drawLocation(ctx, locCoord,[app.globalData.primID,...app.globalData.affiID])
        })
      }
    }, timer.drawTTL);

    // 获取位置
    timer.getLocation = setInterval(() => {
      if (app.globalData.primID && flag.primToken) {
        that.getLocation(app.globalData.primID).then( rCoord => {
          if(rCoord == undefined){
            flag.primToken = false
            if(timer.primReq == undefined){
              if(!that.data.alert.show) alertApi.tipsError(that, "服务器未响应设备", 6000)
              timer.primReq = setTimeout(function(){timer.primReq = undefined; flag.primToken = true}, 8000)
            }
          }
          else{
            that.checkLocation(rCoord)
            var canvasCoord = that.covCoord(rCoord, info, 2)
            if(canvasCoord) primCoord = canvasCoord
          }
        })
      }
      for(let i in app.globalData.affiID){
        if(flag.affiToken[i]) that.getLocation(app.globalData.affiID[i]).then( rCoord => {
          if(rCoord == undefined){
            flag.affiToken[i] = false
            if(timer.affiReq[i] == undefined){
              if(!that.data.alert.show) alertApi.tipsError(that, "服务器未响应设备", 6000)
              timer.affiReq[i] = setTimeout(function(){timer.affiReq[i] = undefined; flag.affiToken[i] = TextTrackCue}, 8000)
            }
          }
          else{
            var canvasCoord = that.covCoord(rCoord, info, 2)
            if(canvasCoord) affiCoord[i] = canvasCoord
          }
        })
      }
    }, timer.getTTL);
  },

  onHide: function () {
    clearInterval(timer.drawCanvas)
    clearInterval(timer.getLocation)
    for(var i in timer.affiReq){
      if(timer.affiReq[i] != undefined){
        clearTimeout(timer.affiReq[i])
        timer.affiReq[i] = undefined
        flag.affiToken[i] = true  
      }
    }
    if(timer.primReq != undefined){
      clearTimeout(timer.primReq)
      timer.primReq == undefined
      flag.primToken = true
    } 
  },

  getLocation: async function (ID) { // 请求获取用户当前位置
    /*("https://lotdata.gdyzx.xyz/getLoction")*/
    /*("https://313641ny65.imdo.co/GetLocation/" + ID)*/
    var rCoord = await utilApi.requestPromise
    ("https://313641ny65.imdo.co/GetLocation/" + ID)
    .then(res => {
      return {
        x:res.data.currentPositionX * 100 - 0,//单位转换：米->厘米
        y:res.data.currentPositionY * 100 + 5
      }
    },function (res) { return undefined })
    return rCoord
  },

  checkLocation: function (rCoord) {
    /* 检查当前位置是否在禁区中 */
    var OOLFlag = false
    for(var area of info.rOOLArea){
      if(rCoord.x >= area.x1 && rCoord.x <= area.x2 && rCoord.y >= area.y1 && rCoord.y <= area.y2 )
        OOLFlag = true
    }
    if(OOLFlag){
      // 警报声
      if(flag.onPlayID != -1) {audio[flag.onPlayID].stop();flag.onPlayID = -1}
      if(app.globalData.set.warnVoice && flag.warnAudio == false){
        flag.warnAudio = true
        warnAudio.play()
      }
      // 震动
      if(app.globalData.set.warnVibrate && flag.warnVibrate == false){
        flag.warnVibrate = true
        wx.vibrateLong('heavy')
        setTimeout(function () {
          flag.warnVibrate = false
        },1000)
      }
      // 提示
      if(!that.data.alert.show){
        flag.warnAlert = true
        alertApi.tipsError(that, "您已进入未授权区域")
      } 
    }
    else{
      if(flag.warnAudio) { warnAudio.stop();flag.warnAudio = false;}
      if(flag.warnAlert){
        alertApi.hideTips(that)
        flag.warnAlert = false
      }
    }

    /* 导航状态下：检查当前位置是否到达终点：语音播报，取消导航 */
    if(that.data.flag.nav){
      var i = app.globalData.tourOrder[0]
      if(rCoord.x >= exhArea[i].x1 && rCoord.x <= exhArea[i].x2
      && rCoord.y >= exhArea[i].y1 && rCoord.y <= exhArea[i].y2){
        flag.exhArr[i] = false
        app.globalData.tourOrder.shift()
        app.globalData.restOrder.push(i)
        if(app.globalData.tourOrder.length == 0) that.endNavigation()
        if(flag.onPlayID != -1){audio[flag.onPlayID].stop();flag.onPlayID = -1} 
        if(app.globalData.set.guideVoice) {audio[i].play(); flag.onPlayID = i}
        this.showLeftDrawer(i)
        return
      }
    }
    for(var i in exhArea){
      if(flag.exhArr[i] == true
      && rCoord.x >= exhArea[i].x1 && rCoord.x <= exhArea[i].x2
      && rCoord.y >= exhArea[i].y1 && rCoord.y <= exhArea[i].y2){
          flag.exhArr[i] = false
          if(flag.onPlayID != -1){audio[flag.onPlayID].stop();flag.onPlayID = -1} 
          if(app.globalData.set.guideVoice) {
            audio[i].play();
            flag.onPlayID = i;
          }
          this.showLeftDrawer(i)
          return
      }
    }
  },

  covCoord: function (coord, info, method = 1) {
    if(method == 1){     //canvas画布坐标转换为方格坐标
      return {
        x: Math.ceil(coord.x / info.grid.size),
        y: Math.ceil(coord.y / info.grid.size)
      }
    }
    else if(method == 2){  //将真实坐标(cm)转换为canvas画布坐标
      if(coord.x < 0 || coord.x > info.map.max_x || coord.y < 0 || coord.y > info.map.max_y) 
        return undefined
      return {
        x: (1 - (coord.y / info.map.max_y)) * info.de.width,
        y: (coord.x / info.map.max_x) * (info.de.width * info.bgpic.ratio),
      }
    }
    else if(method == 3){ //将真实区域坐标(cm)转换为canvas画布坐标
      return {
        "y1":(coord.x1 / info.map.max_x) * (info.de.width * info.bgpic.ratio),
        "y2":(coord.x2 / info.map.max_x) * (info.de.width * info.bgpic.ratio),
        "x2":(1 - (coord.y1 / info.map.max_y)) * info.de.width,
        "x1":(1 - (coord.y2 / info.map.max_y)) * info.de.width,
      }
    }
  },

  getRoutes: function (desID) { // A*算法，获取当前位置到目标位置的路线
    var grid = this.covCoord(primCoord, info, 1)
    var start = [grid.x, grid.y]
    var end = [exhDes[desID].x, exhDes[desID].y]

    mapRoute.init(start, end)
    canvasRoute = this.toStraightLine(mapRoute.getResult())
    canvas.drawRoute_flag = true
  },

  bannedMap: function (map2d) {
   for(var barrier of barriers)
     for(var i = barrier.x1; i <= barrier.x2; i++ )
       for (var j = barrier.y1; j <= barrier.y2; j++ ) map2d[j][i]= 1
  },

  toStraightLine: function (route) { // 将逐个的路线点转换为直线关键点，通过比较两点斜率删去无用点
    if(route.length < 2) return route
    var res = [route[0]]
    var k1 = (route[1].x-route[0].x) / (route[1].y-route[0].y), k2
    for(var i = 2 ; i < route.length; i ++ ){
      k2 = (route[i].x-route[i-1].x) / (route[i].y-route[i-1].y)
      if(k2 != k1) res.push(route[i-1])
      k1 = k2
    }
    res.push(route[route.length-1])
    return res
  },

  addDevice: function () {
    this.data.flag.scan = true
    this.setData({ flag: that.data.flag })
    wx.scanCode({
      onlyFromCamera: false,
    }).then(res=>{
      if(app.addID(res.result)){
        alertApi.tipsSuccess(that, "新成员添加成功", 3000)
        flag.affiToken.push(true)
      } 
      else alertApi.tipsError(that, "添加失败", 3000)
    },function (fail) { 
      alertApi.tipsInfo(that, "未完成扫码", 3000)
    }).finally( ()=>{
       that.data.flag.scan = false;
       that.setData({ flag: that.data.flag })
    })
  },

  startNavigation: function () {  // 开始路径导航
    if(app.globalData.tourOrder.length <= 0){
      alertApi.tipsInfo(that, "请前往游览页面选择地点", 3000)
      flag.tourNav = true
      setTimeout(()=>{
        flag.tourNav = false
      },3000)
    } 
    else{
      this.data.flag.nav = true
      this.setData({ flag: that.data.flag })

      timer.getRoutes = setInterval(()=>{
        if(app.globalData.tourOrder.length <= 0) this.endNavigation()
        else that.getRoutes( app.globalData.tourOrder[0] ) 
      }, timer.navTTL)
    }
  },
 
  endNavigation: function () {  //关闭路径导航
    this.data.flag.nav = false
    this.setData({ flag: that.data.flag })

    clearInterval(timer.getRoutes)
    timer.getRoutes = undefined
  },

  showLeftDrawer(i) {
    that.data.showLeft.show = true
    that.data.showLeft.intro = app.globalData.intro[i]
    this.setData({
        showLeft: that.data.showLeft
    });
  },
  hideLeftDrawer() {
    that.data.showLeft.show = false
    this.setData({
        showLeft: that.data.showLeft
    });
  },
  jumpToPage(){
    if(flag.idNav){
      wx.switchTab({
        url: '/pages/me/me',
      })
    }
    else if(flag.tourNav){
      wx.switchTab({
        url: '/pages/tour/tour',
      })
    }
  }
})